﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Authorization.User/CurrentUser 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       CurrentUser
* 创建时间：  2025/5/24 10:34:48
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using Microsoft.AspNetCore.Http;
using SSPivot.AspNetCore.Abstractions.User;
using SSPivot.Authorization.Security;
using SSPivot.Common.Cache;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace SSPivot.Authorization.User
{
    public partial class CurrentUser : ICurrentUser
    {
        private readonly ICurrentPrincipalAccessor _principalAccessor;
        private readonly ICacheService _cache;
        private readonly IHttpContextAccessor _accessor;
        public CurrentUser(ICurrentPrincipalAccessor principalAccessor, IHttpContextAccessor httpContextAccessor,
            ICacheService cacheService)
        {
            _principalAccessor = principalAccessor;
            _accessor = httpContextAccessor;
            _cache = cacheService;
        }

        private static readonly Claim[] EmptyClaimsArray = new Claim[0];

        public virtual bool IsAuthenticated => Id.HasValue;
        public virtual string Platform => this.FindClaimValue(SSPivotClaimTypes.Platform);

        public virtual long? Id => _principalAccessor.Principal?.FindUserId();

        public virtual string Account => this.FindClaimValue(SSPivotClaimTypes.Account);

        public virtual string Name => this.FindClaimValue(SSPivotClaimTypes.Name);

        public virtual string SurName => this.FindClaimValue(SSPivotClaimTypes.SurName);

        public virtual string PhoneNumber => this.FindClaimValue(SSPivotClaimTypes.PhoneNumber);

        public virtual bool PhoneNumberVerified => string.Equals(this.FindClaimValue(SSPivotClaimTypes.PhoneNumberVerified), "true", StringComparison.InvariantCultureIgnoreCase);

        public virtual string Email => this.FindClaimValue(SSPivotClaimTypes.Email);

        public virtual bool EmailVerified => string.Equals(this.FindClaimValue(SSPivotClaimTypes.EmailVerified), "true", StringComparison.InvariantCultureIgnoreCase);

        public virtual long? TenantId => _principalAccessor.Principal?.FindTenantId();
        public virtual string? TenantName => _principalAccessor.Principal?.FindTenantName();

        public virtual string[] Roles => FindClaims(ClaimTypes.Role).Select(c => c.Value).Distinct().ToArray();

        public virtual string RoleScope => this.FindClaimValue(SSPivotClaimTypes.RoleScope);

        public virtual string Source => this.FindClaimValue(SSPivotClaimTypes.Source);
        /// <summary>
        /// 用户类型
        /// </summary>
        public virtual UserType Type
        {
            get
            {
                var userType = this.FindClaim(SSPivotClaimTypes.UserType);
                if (userType != null && userType.Value.IsNotNullOrWhiteSpace())
                {
                    return (UserType)Enum.Parse(typeof(UserType), userType.Value, true);
                }
                return UserType.DefaultUser;
            }
        }

        /// <summary>
        /// 默认用户
        /// </summary>
        public virtual bool DefaultUser
        {
            get
            {
                return Type == UserType.DefaultUser;
            }
        }

        /// <summary>
        /// 平台管理员
        /// </summary>
        public virtual bool PlatformAdmin
        {
            get
            {
                return Type == UserType.PlatformAdmin;
            }
        }
        /// <summary>
        /// 租户管理员
        /// </summary>
        public virtual bool TenantAdmin
        {
            get
            {
                return Type == UserType.TenantAdmin;
            }
        }

        public virtual Claim FindClaim(string claimType)
        {
            return _principalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == claimType);
        }

        public virtual Claim[] FindClaims(string claimType)
        {
            return _principalAccessor.Principal?.Claims.Where(c => c.Type == claimType).ToArray() ?? EmptyClaimsArray;
        }

        public virtual Claim[] GetAllClaims()
        {
            return _principalAccessor.Principal?.Claims.ToArray() ?? EmptyClaimsArray;
        }

        public virtual bool IsInRole(string roleName)
        {
            return FindClaims(ClaimTypes.Role).Any(c => c.Value == roleName);
        }



        /// <summary>
        ///    数据权限
        /// </summary>
        public DataPermissionDto DataPermission => _cache.Get<DataPermissionDto>(CacheKeys.GetDataPermissionKey(this.Id.Value));

        /// <summary>
        ///      用户权限
        /// </summary>
        public UserPermissionDto UserPermission => _cache.Get<UserPermissionDto>(CacheKeys.GetUserPermissionKey(this.Id.Value));

        /// <summary>
        /// 检查用户是否拥有某个权限点
        /// </summary>
        /// <param name="permissionCode">权限点编码</param>
        /// <returns></returns>
        public virtual bool HasPermission(string permissionCode)
        {
            ArgumentNullException.ThrowIfNull(permissionCode, nameof(permissionCode));

            return HasPermissions([permissionCode]);
        }
        public bool HasPermissions(string[] permissionCodes, bool all = false)
        {
            ArgumentNullException.ThrowIfNull(permissionCodes, nameof(permissionCodes));
            if (PlatformAdmin)
            {
                return true;
            }

            var valid = false;
            if (all)
            {
                valid = UserPermission.Codes.All(a => permissionCodes.Contains(a));
            }
            else
            {
                valid = UserPermission.Codes.Any(a => permissionCodes.Contains(a));
            }

            return valid;
        }
    }
}
